package com.csair.platform.cit.service.dao;

import com.csair.invoice.common.base.util.CastUtil;
import com.csair.invoice.common.base.vo.easyui.PageParam;
import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * jpa原生sql查询实现类
 * @author liaoxiaojin
 *
 */
@Repository
public class JpaBaseDaoImpl implements IJpaBaseDao {

	/**
	 * jpa持久化容器
	 */
	@PersistenceContext
	private EntityManager entityManager;
	
	@Override
	public List<Object[]> findBySql(String sql, Map<String, Object> params) {
		Query q =  entityManager.createNativeQuery(sql.toString());
		if(params != null) {
			for (Entry<String, Object> entry : params.entrySet()) {  
				if(entry.getValue() instanceof Collection<?>) {
					q.setParameter(entry.getKey(), (Collection<?>) entry.getValue());
				} else if(entry.getValue() instanceof Object[]) {
					q.setParameter(entry.getKey(), (Object[]) entry.getValue());
				} else {
					q.setParameter(entry.getKey(), entry.getValue());
				}
			} 
		}
		
		List<Object[]> list = q.getResultList();
		return list;
	}

	@Override
	public long countBySql(String sql, Map<String, Object> params) {
		Query q =  entityManager.createNativeQuery(sql.toString());
		if(params != null) {
			for (Entry<String, Object> entry : params.entrySet()) {  
				if(entry.getValue() instanceof Collection<?>) {
					q.setParameter(entry.getKey(), (Collection<?>) entry.getValue());
				} else if(entry.getValue() instanceof Object[]) {
					q.setParameter(entry.getKey(), (Object[]) entry.getValue());
				} else {
					q.setParameter(entry.getKey(), entry.getValue());
				}
			} 
		}
		
		Object count  = q.getSingleResult();
		long longCount = CastUtil.castLong(count); 
		return longCount;
	}

	@Override
	public List<Object[]> findPageBySql(String sql, Map<String, Object> params, PageParam pageParam) {
		Query q = entityManager.createNativeQuery(sql.toString());
		if(params != null) {
			for (Entry<String, Object> entry : params.entrySet()) {  
				if(entry.getValue() instanceof Collection<?>) {
					q.setParameter(entry.getKey(), (Collection<?>) entry.getValue());
				} else if(entry.getValue() instanceof Object[]) {
					q.setParameter(entry.getKey(), (Object[]) entry.getValue());
				} else {
					q.setParameter(entry.getKey(), entry.getValue());
				}
			} 
		}
		
		q.setFirstResult((pageParam.getPageIndex()-1)*pageParam.getPageSize());
		q.setMaxResults(pageParam.getPageSize());
		List<Object[]> list = q.getResultList();
		return list;
	}

	@Override
	public List findPageBySql(String sql, Map<String, Object> params, PageParam pageParam, Class clz) {
		Query q =  entityManager.createNativeQuery(sql.toString());
		if(params != null) {
			for (Entry<String, Object> entry : params.entrySet()) {  
				if(entry.getValue() instanceof Collection<?>) {
					q.setParameter(entry.getKey(), (Collection<?>) entry.getValue());
				} else if(entry.getValue() instanceof Object[]) {
					q.setParameter(entry.getKey(), (Object[]) entry.getValue());
				} else {
					q.setParameter(entry.getKey(), entry.getValue());
				}
			} 
		}
		q.setFirstResult((pageParam.getPageIndex()-1)*pageParam.getPageSize());
		q.setMaxResults(pageParam.getPageSize());
		List list = q.unwrap(NativeQuery.class).setResultTransformer(Transformers.aliasToBean(clz)).getResultList();
		return list;
	}

	@Override
	public List findBySql(String sql, Map<String, Object> params, Class clz) {
		Query q =  entityManager.createNativeQuery(sql.toString(), clz);
		if(params != null) {
			for (Entry<String, Object> entry : params.entrySet()) {  
				if(entry.getValue() instanceof Collection<?>) {
					q.setParameter(entry.getKey(), (Collection<?>) entry.getValue());
				} else if(entry.getValue() instanceof Object[]) {
					q.setParameter(entry.getKey(), (Object[]) entry.getValue());
				} else {
					q.setParameter(entry.getKey(), entry.getValue());
				}
			} 
		}
		
		List list = q.getResultList();
		return list;
	}

}
